<!--
  文件用途：管理后台首页（老板视角仪表盘，仅注释，不改逻辑）
  核心模块：
  - Hero 胶囊区：关键 KPI 与快捷入口按钮
  - 快捷入口卡片：公司概览/团队/看板/用户/日志/评论
  - 最近动态：聚合日程/日志/评论时间线
  交互说明：
  - 顶部按钮通过 go() 跳转不同功能页
  - recentActivities 由 load() 聚合后端多个接口
-->
<template>
  <el-space direction="vertical" fill>
    <!-- 老板视角 · 欢迎区（Hero） -->
    <div class="hero-section">
      <div class="hero-background"></div>
      <div class="hero-content">
        <div class="hero-text">
          <div class="hello">{{ greet }}，{{ bossName }}</div>
          <div class="sub">公司管理台：关键指标、进展与风险总览。</div>
          <div class="date">{{ todayText }}</div>
          <div class="hero-actions">
            <el-button type="primary" size="large" @click="go('/overview/company')">
              <el-icon><TrendCharts /></el-icon>
              公司概览
            </el-button>
            <el-button size="large" @click="go('/teams')">
              <el-icon><User /></el-icon>
              团队管理
            </el-button>
            <el-button size="large" @click="go('/kanban')">
              <el-icon><Grid /></el-icon>
              看板总览
            </el-button>
            <el-button size="large" @click="go('/users')">
              <el-icon><User /></el-icon>
              用户管理
            </el-button>
          </div>
        </div>
        <div class="hero-illustration">
          <div class="floating-card card-1"></div>
          <div class="floating-card card-2"></div>
          <div class="floating-card card-3"></div>
        </div>
      </div>
      <div class="hero-metrics">
        <div class="pill"><span class="pill-title">用户</span><span class="pill-value">{{ usersTotal }}</span></div>
        <div class="pill"><span class="pill-title">看板</span><span class="pill-value">{{ kanbanCount }}</span></div>
        <div class="pill"><span class="pill-title">日程</span><span class="pill-value">{{ scheduleCount }}</span></div>
        <div class="pill"><span class="pill-title">日志</span><span class="pill-value">{{ worklogCount }}</span></div>
        <div class="pill" v-if="isAdmin"><span class="pill-title">评论</span><span class="pill-value">{{ commentsTotal }}</span></div>
      </div>
    </div>

    <!-- 快捷入口（老板常用） -->
    <el-card class="quick-access-card" shadow="never">
      <template #header>
        <div class="section-header">
          <div class="section-title">
            <el-icon class="section-icon"><Grid /></el-icon>
            快捷入口
          </div>
        </div>
      </template>
      <div class="app-grid">
        <div class="app-tile company-tile" @click="go('/overview/company')">
          <div class="tile-icon"><el-icon><TrendCharts /></el-icon></div>
          <div class="tile-content">
            <div class="tile-title">公司概览</div>
            <div class="tile-desc">关键指标与趋势</div>
          </div>
        </div>
        <div class="app-tile teams-tile" @click="go('/teams')">
          <div class="tile-icon"><el-icon><User /></el-icon></div>
          <div class="tile-content">
            <div class="tile-title">团队管理</div>
            <div class="tile-desc">团队与成员管理</div>
          </div>
        </div>
        <div class="app-tile kanban-tile" @click="go('/kanban')">
          <div class="tile-icon"><el-icon><Grid /></el-icon></div>
          <div class="tile-content">
            <div class="tile-title">看板总览</div>
            <div class="tile-desc">项目与流程</div>
          </div>
        </div>
        <div class="app-tile users-tile" @click="go('/users')">
          <div class="tile-icon"><el-icon><User /></el-icon></div>
          <div class="tile-content">
            <div class="tile-title">用户管理</div>
            <div class="tile-desc">账号与权限</div>
          </div>
        </div>
        <div class="app-tile worklogs-tile" @click="go('/worklogs')">
          <div class="tile-icon"><el-icon><Document /></el-icon></div>
          <div class="tile-content">
            <div class="tile-title">日志管理</div>
            <div class="tile-desc">日志与进度</div>
          </div>
        </div>
        <div class="app-tile comments-tile" @click="go('/comments')">
          <div class="tile-icon"><el-icon><ChatDotRound /></el-icon></div>
          <div class="tile-content">
            <div class="tile-title">评论管理</div>
            <div class="tile-desc">评论与反馈</div>
          </div>
        </div>
      </div>
    </el-card>
  <!-- 老板要求：移除旧的统计卡片与系统状态卡片（保留上方 Hero 胶囊指标） -->

    <!-- 系统告警 -->
    <el-card v-if="alerts && alerts.length" style="margin-bottom: 16px;">
      <template #header>
        <div class="card-header">
          <span>系统告警</span>
        </div>
      </template>
      <div>
        <el-alert
          v-for="(a, idx) in alerts"
          :key="idx"
          :title="a.title"
          :type="a.type"
          :description="a.desc"
          :closable="false"
          show-icon
          style="margin-bottom: 10px;"
        />
      </div>
    </el-card>



    <!-- 最近动态 -->
    <el-card class="recent-activity">
      <template #header>
        <div class="card-header">
          <span>最近动态</span>
        </div>
      </template>
      <el-skeleton :loading="loading.schedules || loading.worklogs || loading.comments" animated>
        <template #template>
          <div class="timeline-skeleton">
            <el-skeleton-item variant="circle" style="width: 40px; height: 40px; margin-right: 16px;" />
            <div style="flex: 1;">
              <el-skeleton-item variant="p" style="width: 60%; margin-bottom: 8px;" />
              <el-skeleton-item variant="text" style="width: 40%;" />
            </div>
          </div>
          <div class="timeline-skeleton">
            <el-skeleton-item variant="circle" style="width: 40px; height: 40px; margin-right: 16px;" />
            <div style="flex: 1;">
              <el-skeleton-item variant="p" style="width: 70%; margin-bottom: 8px;" />
              <el-skeleton-item variant="text" style="width: 50%;" />
            </div>
          </div>
          <div class="timeline-skeleton">
            <el-skeleton-item variant="circle" style="width: 40px; height: 40px; margin-right: 16px;" />
            <div style="flex: 1;">
              <el-skeleton-item variant="p" style="width: 80%; margin-bottom: 8px;" />
              <el-skeleton-item variant="text" style="width: 30%;" />
            </div>
          </div>
        </template>
        <template #default>
          <template v-if="(recentActivities && recentActivities.length) > 0">
            <el-timeline>
            <el-timeline-item
              v-for="activity in recentActivities"
              :key="activity.id"
              :icon="activity.icon"
              :type="activity.type"
              :color="activity.color"
              :timestamp="activity.timestamp"
              placement="top"
            >
              <el-card class="activity-card">
                <div class="activity-content">
                  <div class="activity-title" @click="activity.to && go(activity.to)" style="cursor: pointer;">
                    <component :is="activity.icon" class="activity-icon" />
                    <span>{{ activity.title }}</span>
                  </div>
                  <div class="activity-description">{{ activity.description }}</div>
                  <div class="activity-meta">
                    <div class="meta-left">
                      <template v-for="t in activity.tags || [{ text: activity.category, type: activity.tagType }]" :key="t.text + t.type">
                        <el-tag v-if="!t.to" :type="t.type" size="small" style="margin-right:6px">{{ t.text }}</el-tag>
                        <el-link v-else type="primary" @click.stop="go(t.to)" style="margin-right:6px">{{ t.text }}</el-link>
                      </template>
                    </div>
                    <span class="activity-user">{{ activity.user }}</span>
                  </div>
                </div>
              </el-card>
            </el-timeline-item>
            </el-timeline>
          </template>
          <template v-else>
            <el-empty description="暂无最近动态">
              <el-button type="primary" @click="load">刷新</el-button>
            </el-empty>
          </template>
        </template>
      </el-skeleton>
    </el-card>
  </el-space>
  
  
</template>

<script setup>
import { ref, onMounted, markRaw } from 'vue'
import { useRouter } from 'vue-router'
import { api } from '@/utils/api'
import { User, Grid, Calendar, Document, ChatDotRound, TrendCharts } from '@element-plus/icons-vue'

const role = localStorage.getItem('role') || ''
const isAdmin = role === 'admin'
const router = useRouter()

// 老板称谓与问候
const bossName = ref(localStorage.getItem('username') || '管理员')
const greet = ref('')
const todayText = ref('')
function computeGreeting() {
  const h = new Date().getHours()
  greet.value = h < 6 ? '凌晨好' : h < 12 ? '早上好' : h < 14 ? '中午好' : h < 18 ? '下午好' : '晚上好'
  const d = new Date()
  const w = ['日','一','二','三','四','五','六'][d.getDay()]
  todayText.value = `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')} 星期${w}`
}

// 顶部指标
const scheduleCount = ref(0) // 系统日程总数
const kanbanCount = ref(0)   // 系统看板总数
const worklogCount = ref(0)  // 系统日志总数
const usersTotal = ref(0)    // 系统用户总数
const commentsTotal = ref(0) // 系统评论总数
const health = ref({ ok: false, text: '未连通' })

// 全量数据（系统范围）用于趋势与告警
const allSchedules = ref([])
const allWorklogs = ref([])
const allComments = ref([])
const allUsers = ref([])





// 最近动态数据
const recentActivities = ref([])

function go(to) {
  if (to) router.push(to)
}



// 告警
const alerts = ref([])
function computeAlerts() {
  const arr = []
  if (!health.value.ok) {
    arr.push({ type: 'error', title: '后端未连通', desc: '请检查服务状态与前端代理配置。' })
  }
  // 日程超期
  let overdue = 0
  const now = Date.now()
  const titles = []
  for (const s of allSchedules.value || []) {
    const st = (s.status||'').toLowerCase()
    const et = s.endTime
    if (!et) continue
    const dt = new Date(String(et).includes('T') ? et : String(et).replace(' ', 'T'))
    const ms = dt.getTime()
    if (!isNaN(ms) && ms < now && st !== 'done' && st !== 'canceled') {
      overdue++
      if (titles.length < 3) titles.push(s.title || `日程#${s.scheduleId}`)
    }
  }
  if (overdue > 0) {
    arr.push({ type: 'warning', title: '日程超期', desc: `有 ${overdue} 个日程已超过截止时间：${titles.join('，')}${overdue>titles.length?' 等':''}` })
  }
  alerts.value = arr
}

const loading = ref({ schedules: false, worklogs: false, comments: false, users: false, kanbans: false, alerts: false })

// 将任意返回值规范化为数组；若是 JSON 字符串尝试解析
function toArray(x) {
  if (Array.isArray(x)) return x
  if (x && typeof x === 'string') {
    try {
      const j = JSON.parse(x)
      if (Array.isArray(j)) return j
    } catch {}
  }
  return []
}

async function load() {
  // 健康检查：只要能拿到任一数据即视为连通
  let connected = false

  // 加载日程相关（数量、列表）
  loading.value.schedules = true
  try {
    const list = await api.get('/api/schedule')
    // 兼容数组或分页结构
    if (list && Array.isArray(list.records)) {
      allSchedules.value = list.records
      scheduleCount.value = Number(list.total || list.records.length || 0)
    } else if (list && typeof list === 'object' && 'records' in list) {
      allSchedules.value = toArray(list.records)
      scheduleCount.value = Number(list.total || allSchedules.value.length || 0)
    } else {
      allSchedules.value = toArray(list)
      scheduleCount.value = allSchedules.value.length
    }
    connected = true
  } catch {
    allSchedules.value = []
  } finally {
    loading.value.schedules = false
  }

  // 加载看板数量
  try {
    const kb = await api.get('/api/kanban/all')
    kanbanCount.value = Array.isArray(kb) ? kb.length : 0
    connected = true
  } catch {}

  // 加载日志（数量与最近）
  loading.value.worklogs = true
  try {
    const wl = await api.get('/worklog/list')
    if (wl && Array.isArray(wl.records)) {
      allWorklogs.value = wl.records
      worklogCount.value = Number(wl.total || wl.records.length || 0)
    } else if (wl && typeof wl === 'object' && 'records' in wl) {
      allWorklogs.value = toArray(wl.records)
      worklogCount.value = Number(wl.total || allWorklogs.value.length || 0)
    } else {
      allWorklogs.value = toArray(wl)
      worklogCount.value = allWorklogs.value.length
    }
    connected = true
  } catch {
  } finally {
    loading.value.worklogs = false
  }

  // 汇总用户总数与用户映射
  try {
    const users = await api.get('/user/list', { page: 1, size: 1000 })
    let arr = []
    if (users && Array.isArray(users.records)) arr = users.records
    else if (users && typeof users === 'object' && 'records' in users) arr = toArray(users.records)
    else if (Array.isArray(users)) arr = users
    else arr = toArray(users)
    allUsers.value = arr
    usersTotal.value = arr.length
    connected = true
  } catch {}

  // 评论总数与最新评论（管理员接口）
  loading.value.comments = true
  try {
    if (isAdmin) {
      const comments = await api.get('/comment/list/all')
      allComments.value = toArray(comments)
      commentsTotal.value = allComments.value.length
      connected = true
    }
  } catch {
  } finally {
    loading.value.comments = false
  }

  health.value = connected ? { ok: true, text: '后端已连通' } : { ok: false, text: '后端未连通' }
   
  // 加载最近动态
  await loadRecentActivities()
  computeAlerts()
}

// 加载最近动态
async function loadRecentActivities() {
  const activities = []

  // 构建映射，便于关联信息展示
  const usersArr = toArray(allUsers.value)
  const schedulesArr = toArray(allSchedules.value)
  const worklogsArr = toArray(allWorklogs.value)
  const commentsArr = toArray(allComments.value)

  const userById = new Map(usersArr.map(u => [u.userId, u]))
  const uname = (id) => {
    const u = userById.get(id)
    return u ? (u.nickname || u.username || `用户#${id}`) : (id ? `用户#${id}` : '用户')
  }
  const scheduleById = new Map(schedulesArr.map(s => [s.scheduleId, s]))
  const worklogById = new Map(worklogsArr.map(w => [w.worklogId, w]))
  const fmtDate = (v) => {
    if (!v) return ''
    const s = typeof v === 'string' ? (v.includes('T') ? v : v.replace(' ', 'T')) : v
    const d = new Date(s)
    if (isNaN(d)) return ''
    const pad = (n)=> String(n).padStart(2,'0')
    return `${d.getFullYear()}-${pad(d.getMonth()+1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`
  }

  // 日程：取近 50 条参与排序（避免全量过大）
  schedulesArr.slice(-50).forEach(s => {
    const tags = [
      { text: '日程', type: 'primary', to: s?.scheduleId ? `/schedule/${s.scheduleId}` : undefined },
      s.status ? { text: `状态:${s.status}`, type: s.status==='done'?'success':(s.status==='doing'?'warning':'info') } : null,
      s.priority ? { text: `优先:${s.priority}`, type: s.priority==='high'?'danger':(s.priority==='medium'?'warning':'info') } : null,
      s.endTime ? { text: `截止:${fmtDate(s.endTime).slice(0,16)}`, type: 'info' } : null,
    ].filter(Boolean)
    activities.push({
      id: `schedule-${s.scheduleId}`,
      title: `${uname(s.creatorId)} 创建了日程` ,
      description: `“${s.title}”` ,
      timestamp: s.createTime || s.startTime,
      category: '日程',
      tagType: 'primary',
      user: uname(s.creatorId),
      icon: markRaw(Calendar),
      type: 'primary',
      color: '#409EFF',
      tags,
      to: s?.scheduleId ? `/schedule/${s.scheduleId}` : undefined
    })
  })

  // 工作日志：近 50 条
  worklogsArr.slice(-50).forEach(w => {
    const rel = w.relatedScheduleId ? scheduleById.get(w.relatedScheduleId) : null
    const tags = [
      { text: '日志', type: 'success', to: w?.worklogId ? `/worklogs/${w.worklogId}` : undefined },
      w.logDate ? { text: `日期:${String(w.logDate)}`, type: 'info' } : null,
      rel ? { text: `关联:${rel.title || ('日程#'+rel.scheduleId)}`, type: 'primary', to: rel?.scheduleId ? `/schedule/${rel.scheduleId}` : undefined } : null,
    ].filter(Boolean)
    const snippet = (w.title && w.title.trim().length>0 ? w.title : (w.content || '')).toString().slice(0, 40)
    activities.push({
      id: `worklog-${w.worklogId}`,
      title: `${uname(w.creatorId)} 提交了工作日志`,
      description: snippet ? `${snippet}${(w.content||'').length>40 ? '…':''}` : '提交了日志',
      timestamp: w.createTime || w.logDate,
      category: '日志',
      tagType: 'success',
      user: uname(w.creatorId),
      icon: markRaw(Document),
      type: 'success',
      color: '#67C23A',
      tags,
      to: w?.worklogId ? `/worklogs/${w.worklogId}` : undefined
    })
  })

  // 评论：仅管理员可见（近 50 条）
  if (isAdmin) {
  commentsArr.slice(-50).forEach(c => {
      const isSched = String(c.relatedType||'').toLowerCase()==='schedule'
      const isWl = String(c.relatedType||'').toLowerCase()==='worklog'
      const target = isSched ? scheduleById.get(c.relatedId) : (isWl ? worklogById.get(c.relatedId) : null)
      const targetTitle = target ? (target.title || (isSched?`日程#${target.scheduleId}`:`日志#${target.worklogId}`)) : `${c.relatedType}#${c.relatedId}`
      const tags = [
    { text: '评论', type: 'warning' },
    { text: `对象:${isSched?'日程':isWl?'日志':String(c.relatedType)}`, type: 'info' },
    target ? { text: `主题:${targetTitle}`, type: 'primary', to: isSched ? `/schedule/${target.scheduleId}` : (isWl ? `/worklogs/${target.worklogId}` : undefined) } : null,
      ].filter(Boolean)
      activities.push({
        id: `comment-${c.commentId}`,
        title: `${uname(c.creatorId)} 发表了评论`,
        description: (c.content||'').toString().slice(0, 60) + ((c.content||'').length>60?'…':''),
        timestamp: c.createTime,
        category: '评论',
        tagType: 'warning',
        user: uname(c.creatorId),
        icon: markRaw(ChatDotRound),
        type: 'warning',
        color: '#E6A23C',
    tags,
    to: target ? (isSched ? `/schedule/${target.scheduleId}` : (isWl ? `/worklogs/${target.worklogId}` : undefined)) : undefined
      })
    })
  }

  // 排序：优先按时间；若时间缺失/非法，退化为按 id 数字部分倒序
  activities.sort((a, b) => {
    const ta = Date.parse(a.timestamp)
    const tb = Date.parse(b.timestamp)
    if (!isNaN(tb) && !isNaN(ta)) return tb - ta
    const ida = Number(String(a.id||'').split('-').pop()) || 0
    const idb = Number(String(b.id||'').split('-').pop()) || 0
    return idb - ida
  })
  let out = activities.slice(0, 15)
  // 若仍为空，基于原始数组兜底合成
  if (out.length === 0) {
    const synth = []
  schedulesArr.slice(-10).forEach(s=>{
      synth.push({ id:`schedule-${s.scheduleId}`, title:`${uname(s.creatorId)} 创建了日程`, description:`“${s.title}”`, timestamp:s.createTime||s.startTime||new Date().toISOString(), category:'日程', tagType:'primary', user:uname(s.creatorId), icon: Calendar, type:'primary', color:'#409EFF', tags:[{text:'日程',type:'primary'}] })
    })
  worklogsArr.slice(-10).forEach(w=>{
      const snippet = (w.title && w.title.trim().length>0 ? w.title : (w.content || '')).toString().slice(0, 40)
      synth.push({ id:`worklog-${w.worklogId}`, title:`${uname(w.creatorId)} 提交了工作日志`, description: snippet, timestamp: w.createTime||w.logDate||new Date().toISOString(), category:'日志', tagType:'success', user: uname(w.creatorId), icon: Document, type:'success', color:'#67C23A', tags:[{text:'日志',type:'success'}] })
    })
    out = synth.slice(-15).reverse()
  }
  recentActivities.value = out
  try {
    console.debug('[dashboard] schedules=', allSchedules.value.length, 'worklogs=', allWorklogs.value.length, 'comments=', allComments.value.length, 'users=', allUsers.value.length, 'activities=', recentActivities.value.length)
  } catch {}
}



onMounted(load)

// 初始化问候
computeGreeting()
</script>

<style scoped>
/* ======= 欢迎区（Hero） ======= */
.hero-section { position: relative; border-radius: 20px; overflow: hidden; min-height: 220px; display: flex; flex-direction: column; gap: 8px; }
.hero-background { position: absolute; inset: 0; background: linear-gradient(135deg, #3f51b5 0%, #2196f3 100%); opacity: 0.95; }
.hero-content { position: relative; z-index: 1; display: flex; justify-content: space-between; align-items: center; padding: 28px; color: #fff; }
.hero-text { flex: 1; }
.hello { font-size: 28px; font-weight: 700; margin-bottom: 6px; text-shadow: 0 2px 4px rgba(0,0,0,0.12); }
.sub { font-size: 14px; opacity: 0.95; margin-bottom: 6px; line-height: 1.5; }
.date { font-size: 12px; opacity: 0.9; margin-bottom: 16px; }
.hero-actions { display: flex; gap: 10px; flex-wrap: wrap; }
.hero-actions .el-button { border-radius: 12px; padding: 10px 18px; font-weight: 600; box-shadow: 0 4px 12px rgba(0,0,0,0.15); transition: all .25s ease; }
.hero-actions .el-button:hover { transform: translateY(-1px); box-shadow: 0 6px 18px rgba(0,0,0,0.2); }
.hero-illustration { position: relative; width: 180px; height: 160px; margin-left: 24px; }
.floating-card { position: absolute; border-radius: 12px; background: rgba(255,255,255,0.12); backdrop-filter: blur(10px); border: 1px solid rgba(255,255,255,0.25); }
.card-1 { width: 80px; height: 60px; top: 10px; right: 10px; animation: float 6s ease-in-out infinite; }
.card-2 { width: 100px; height: 72px; top: 48px; right: 48px; animation: float 6s ease-in-out infinite 2s; }
.card-3 { width: 60px; height: 44px; top: 110px; right: 28px; animation: float 6s ease-in-out infinite 4s; }
@keyframes float { 0%,100%{ transform: translateY(0) } 50%{ transform: translateY(-8px) } }
.hero-metrics { position: relative; z-index: 1; display: flex; gap: 8px; padding: 0 12px 12px 12px; flex-wrap: wrap; }
.pill { background: rgba(255,255,255,0.9); color: #303133; border: 1px solid rgba(0,0,0,0.05); padding: 8px 12px; border-radius: 999px; display: inline-flex; align-items: baseline; gap: 8px; }
.pill-title { font-size: 12px; color: #606266; }
.pill-value { font-size: 16px; font-weight: 700; color: #303133; }

/* ======= 快捷入口（Admin） ======= */
.quick-access-card { border: 1px solid #e4e7ed; border-radius: 16px; overflow: hidden; }
.section-header { display: flex; justify-content: space-between; align-items: center; }
.section-title { font-weight: 600; font-size: 18px; display: flex; align-items: center; gap: 8px; }
.section-icon { color: #409eff; }
.app-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 14px; margin-top: 12px; }
.app-tile { display: flex; align-items: center; gap: 12px; padding: 14px; border: 1px solid #ebeef5; border-radius: 12px; cursor: pointer; transition: all .25s ease; background: #fff; }
.app-tile:hover { transform: translateY(-2px); box-shadow: 0 8px 18px rgba(0,0,0,0.06); border-color: #dcdfe6; }
.tile-icon { width: 40px; height: 40px; border-radius: 10px; display: grid; place-items: center; background: #f5f7fa; color: #409eff; }
.tile-content { display: flex; flex-direction: column; }
.tile-title { font-weight: 600; color: #303133; }
.tile-desc { font-size: 12px; color: #909399; margin-top: 2px; }
.company-tile .tile-icon { background: #ecf5ff; color: #409eff; }
.teams-tile .tile-icon { background: #f0f9eb; color: #67c23a; }
.kanban-tile .tile-icon { background: #fdf6ec; color: #e6a23c; }
.users-tile .tile-icon { background: #f4f4f5; color: #909399; }
.worklogs-tile .tile-icon { background: #f0f9eb; color: #67c23a; }
.comments-tile .tile-icon { background: #fdf6ec; color: #e6a23c; }
/* 统计卡片与系统状态已移除 */



/* 时间轴骨架屏样式 */
.timeline-skeleton {
  display: flex;
  align-items: center;
  margin-bottom: 20px;
  padding: 16px 0;
}

/* 最近动态样式（简洁风） */
.recent-activity { border-radius: 10px; border: 1px solid #ebeef5; background: #fff; }

.card-header { font-weight: 600; color: #303133; font-size: 16px; padding: 16px 16px 0 16px; }

.activity-card { margin: 0; box-shadow: none; border: 1px solid #ebeef5; border-radius: 8px; background: #fff; margin-bottom: 10px; }

.activity-content {
  padding: 16px;
}

.activity-title { display: flex; align-items: center; font-weight: 600; margin-bottom: 8px; color: #303133; font-size: 14px; }

.activity-icon { width: 16px; height: 16px; margin-right: 8px; color: #606266; }

.activity-description { color: #606266; font-size: 13px; margin-bottom: 8px; line-height: 1.5; }

.activity-meta { display: flex; justify-content: space-between; align-items: center; font-size: 12px; }

.activity-user { color: #909399; font-size: 12px; font-weight: 500; }

/* 时间轴自定义样式 */
:deep(.el-timeline-item__timestamp) { color: #909399; font-size: 12px; }

:deep(.el-timeline-item__wrapper) { padding-left: 24px; }

:deep(.el-timeline-item__tail) { border-left: 1px solid #e4e7ed; }

:deep(.el-timeline-item__node) { width: 10px; height: 10px; left: -5px; }


</style>
